package uscdb.javaconfig;

import java.sql.SQLException;
import java.util.Properties;
import org.springframework.core.env.Environment;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.alibaba.druid.pool.DruidDataSource;

//事务  
//@EnableTransactionManagement
//@Configuration // 通过该注解表明这是一个spring的配置，相当于xml文件
//@ComponentScan(basePackages = { "uscdb.dao", "uscdb.service", "uscdb.task" }) // 配置扫描包
//@PropertySource(value = { "classpath:config.properties" }, ignoreResourceNotFound = true)
public class SpringConfig {

	@Value("${jdbc_url}")
	private String jdbcUrl;

	@Value("${jdbc_username}")
	private String username;

	@Value("${jdbc_password}")
	private String password;

	@Value("${validationQuery}")
	private String validationQuery;
	
	@Autowired  
    private Environment environment;  

	@Bean(destroyMethod = "close")
	public DruidDataSource druidDataSource() throws SQLException {
		DruidDataSource ds = new DruidDataSource();
		// 配置数据源
		ds.setUrl(jdbcUrl);
		ds.setUsername(username);
		ds.setPassword(password);

		ds.setInitialSize(0);// 初始化连接大小
		ds.setMaxActive(20);// 连接池最大使用连接数量
		ds.setMinIdle(0);// 连接池最小空闲
		ds.setMaxWait(60000);// 获取连接最大等待时间
		ds.setValidationQuery(validationQuery);
		ds.setTestOnBorrow(false);
		ds.setTestOnReturn(false);
		ds.setTestWhileIdle(true);

		// 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
		ds.setTimeBetweenEvictionRunsMillis(60000);
		// 配置一个连接在池中最小生存的时间，单位是毫秒
		ds.setMinEvictableIdleTimeMillis(25200000);

		// 打开removeAbandoned功能
		ds.setRemoveAbandoned(true);
		// 1800秒，也就是30分钟
		ds.setRemoveAbandonedTimeout(1800);
		// 关闭abanded连接时输出错误日志
		ds.setLogAbandoned(true);

		// 监控数据库
		ds.setFilters("stat");

		return ds;
	}
	
	@Bean  
    public LocalSessionFactoryBean sessionFactory() throws SQLException {  
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();  
        sessionFactory.setDataSource(druidDataSource());  
        sessionFactory.setPackagesToScan(new String[] { "uscdb.model" });  
        sessionFactory.setHibernateProperties(hibernateProperties());  
        return sessionFactory;  
     }   
	
	private Properties hibernateProperties() {  
        Properties p = new Properties();  
        
        p.setProperty("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
        p.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));  
        p.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));  
        p.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));  
        
        p.setProperty("hibernate.use_sql_comments", environment.getRequiredProperty("hibernate.use_sql_comments"));
        p.setProperty("hibernate.search.default.indexBase", environment.getRequiredProperty("d:/index"));
        p.setProperty("hibernate.search.default.directory_provider", environment.getRequiredProperty("org.hibernate.search.store.impl.FSDirectoryProvider"));
        
        // 这个启动web项目时候不需要
//        p.setProperty("hibernate.current_session_context_class", environment.getRequiredProperty("thread"));
        return p;          
    }  
	
	@Bean  
    @Autowired  
    public HibernateTransactionManager transactionManager(SessionFactory s) {  
       HibernateTransactionManager txManager = new HibernateTransactionManager();  
       txManager.setSessionFactory(s);  
       return txManager;  
    }  
	
	// TODO 剩下 拦截器方式配置事物 ，配置AOP 已经在TxAdviceInterceptor类实现
	
}
